import type { UserInfoModel } from "./../api/acl/model/loginModel";
// 引入创建仓库的方法defineState
import { defineStore } from "pinia";
// 引入获取token和移除和存储token的方法
import { getToken, removeToken, setToken } from "../utils/token-utils";
// 引入用户信息对象的类型，实际上是一个接口
import type { UserInfoState } from "./interface";
// 引入消息框组件
import { ElMessage } from "element-plus";
// 引入静态路由数组和异步路由数组和任意路由数组
import { staticRoutes, allAsyncRoutes, anyRoute } from "@/router/routes";
// 引入路由器对象
import router from "@/router";
// 引入路由数组的数据类型
import type { RouteRecordRaw } from "vue-router";
// 引入api函数
import { reqLogin, reqLogout, reqUserInfo } from "@/api/acl/login";
// 引入深拷贝
import { cloneDeep } from "lodash";

// 过滤路由的函数
function filterRoutes(asyncRoutes: RouteRecordRaw[], routeNames: string[]) {
  return asyncRoutes.filter((route) => {
    // 判断路由名字数组中是否有路由对象的名字，如果没有就不用过滤
    if (routeNames.indexOf(route.name as string) === -1) return false;
    // 判断当前的路由对象中有没有子路由children
    if (route.children && route.children.length > 0) {
      route.children = filterRoutes(route.children, routeNames);
    }
    return true;
  });
}

//动态注册路由的函数
function addRoutes(routes: RouteRecordRaw[]) {
  routes.forEach((route) => {
    // 遍历每个路由对象，并把路由对象注册到路由器中
    router.addRoute(route);
  });
}

// 重置路由的函数
function resetRouter() {
  // 先获取路由器中所有的路由
  const routes = router.getRoutes();
  // 遍历每个路由对象，从路由器对象中移除
  routes.forEach((route) => {
    if (route.name) {
      // 从路由器对象中移除
      router.removeRoute(route.name as string);
    }
  });
  // 再重新的把静态路由数组中的每一个路由重新的添加到路由器中
  staticRoutes.forEach((r) => router.addRoute(r));
}
/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore("userInfo", {
  // 状态数据
  state: (): UserInfoState => ({
    token: getToken() as string, //先从本地存储中获取token信息
    name: "", //用户名
    avatar: "", //头像信息

    // 和权限相关的数据
    menuRoutes: [], //路由数组
    roles: [], //角色名字数组
    authBtnList: [],
  }),

  actions: {
    async login(username: string, password: string) {
      const { token } = await reqLogin(username, password);
      setToken(token);
      this.token = token;
    },

    async getInfo() {
      const userInfo: UserInfoModel = await reqUserInfo();
      this.name = userInfo.name;
      this.avatar = userInfo.avatar;

      // 先存储角色名字数组的数据
      this.roles = userInfo.roles;
      // 然后存储按钮权限标识数组
      this.authBtnList = userInfo.buttons;

      /* 干掉了this.menRoutes = staticRouters 
      然后过滤完所有的路由数组数据后， 
      再进行存储静态路由火绒异步路由和任意路由 */
      this.setRoutes(userInfo.routes);
    },

    // 定义过滤路由及存储路由的方法
    setRoutes(routeNames: string[]) {
      // 过滤路由
      const asyncRoutes = filterRoutes(cloneDeep(allAsyncRoutes), routeNames);
      // 添加路由（吧过滤后的路由对象数组  重新的放在router路由器中进行路由的注册）
      addRoutes([...asyncRoutes, anyRoute]);
      // 存储路由（吧静态路由，过滤后的异步路由和任意路由放在menuRoutes中 为了页面展示）
      this.menuRoutes = [...staticRoutes, ...asyncRoutes];
    },

    async reset() {
      if (this.name) {
        await reqLogout();
      }
      // 删除local中保存的token
      removeToken();
      // 提交重置用户信息的mutation
      this.token = "";
      this.name = "";
      this.avatar = "";

      // 重置路由
      // 干掉按钮标识数据和路由数据和角色数据
      resetRouter();
      this.menuRoutes = [];
      this.roles = [];
      this.authBtnList = [];
    },
  },
});
